package com.size.mall.order.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.size.mall.config.annotations.LoginRequired;
import com.size.mall.mallapi.entity.*;
import com.size.mall.mallapi.service.CartService;
import com.size.mall.mallapi.service.MemberService;
import com.size.mall.mallapi.service.OrderService;
import com.size.mall.mallapi.service.PmsSkuInfoService;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.ibatis.jdbc.Null;
import org.assertj.core.api.ShortArrayAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static cn.hutool.core.collection.CollUtil.isNotEmpty;

@Controller
@CrossOrigin
public class OrderController {

    @Reference
    OrderService orderService;


    @Reference
    CartService cartService;

    @Reference
    MemberService memberService;


    @Reference
    PmsSkuInfoService skuService;


    @RequestMapping("submitOrder")
    @LoginRequired(loginSuccess = true)
    public ModelAndView submitOrder(String receiveAddressId, BigDecimal totalAmount, String tradeCode,
                                    HttpServletRequest request, HttpServletResponse response, HttpSession session,
                                    ModelMap modelMap) {

        ModelAndView tradeFail = new ModelAndView("tradeFail");


        String memberId = (String) request.getAttribute("memberId");
        String nickname = (String) request.getAttribute("nickname");


        String success = orderService.checkTradeCode(memberId, tradeCode);
        if (success.equals("success")) {


            UmsMemberReceiveAddress shippingAddress =
                    memberService.getAddrByReciveAddressId(receiveAddressId);


            //region 生成订单
            String outTradeNo = "sizemall" + DateUtil.format(new Date(), "YYYYMMDDHHmmss");
            OmsOrder omsOrder = new OmsOrder()
                    .setAutoConfirmDay(7) // 自动收货时间7天
                    .setCreateTime(new Date())
                    .setDiscountAmount(null)
                    // .setFreightAmount() // 生成运费11
                    .setMemberId(memberId)
                    .setMemberUsername(nickname)
                    .setNote("采购产品")
                    .setOrderSn(outTradeNo) // 设置外部订单号
                    .setPayAmount(totalAmount)
                    .setOrderType(1)
                    .setReceiverDetailAddress(shippingAddress.getDetailAddress())
                    .setReceiverCity(shippingAddress.getCity())
                    .setReceiverName(shippingAddress.getName())
                    .setReceiverPhone(shippingAddress.getPhoneNumber())
                    .setReceiverPostCode(shippingAddress.getPostCode())
                    .setReceiverProvince(shippingAddress.getProvince())
                    .setReceiverRegion(shippingAddress.getRegion())
                    .setReceiveTime(DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, 1)) // 配送时间:当前时间加一天
                    .setSourceType(0)
                    .setStatus(0)
                    .setTotalAmount(totalAmount);


            //endregion



            // 根据用户ip获得商品列表 (购物车) 和 总价格
            List<OmsOrderItem> items = new ArrayList<>();

            // 调用购物车
            List<OmsCartItem> omsCartItems = (List<OmsCartItem>) cartService.cartList(memberId);
            if (isNotEmpty(omsCartItems)) {


                for (OmsCartItem cartItem : omsCartItems) {

                    String isChecked = cartItem.getIsChecked();

                    if (!(null == isChecked) && isChecked.equals("1")) {
                        OmsOrderItem orderItem = new OmsOrderItem();

                        boolean b = skuService.checkPrice(cartItem.getProductSkuId(),cartItem.getPrice());

                        if (b == false) {

                            return tradeFail;
                        }


                        orderItem.setProductName(cartItem.getProductName());
                        orderItem.setProductPic(cartItem.getProductPic());
                        orderItem.setProductQuantity(cartItem.getQuantity());
                        orderItem.setOrderSn("sizemall" + DateUtil.format(new Date(), "YYYYMMDDHHmmss"));  // 外部订单
                        orderItem.setProductCategoryId(cartItem.getProductCategoryId());
                        orderItem.setProductPrice(cartItem.getPrice());
                        // 正常还是减去各种优惠券
                        orderItem.setRealAmount(cartItem.getTotalPrice());

                        orderItem.setProductSkuId(cartItem.getProductSkuId());

                        orderItem.setProductId(cartItem.getProductId());
                        orderItem.setProductSn("产品对应的仓库编号"); // 在仓库中的id


                        items.add(orderItem);

                    }


                }

            }



            omsOrder.setOmsOrderItems(items);


            // 再保存订单的同时,删除购物车
            orderService.saveOrder(omsOrder);






            // 重定向到支付系统
            ModelAndView view = new ModelAndView("redirect:http://yin:9090/index");
            //region Description
            view.addObject("totalAmount", totalAmount);
            //endregion
            view.addObject("outTradeNo", outTradeNo);

            return view;

        } else {
            return tradeFail;
        }


    }


    @GetMapping("toTrade")
    @LoginRequired(loginSuccess = true)
    public String toTrade(HttpServletRequest rq, HttpServletResponse rp, HttpSession session, ModelMap model) {


        String memberId = (String) rq.getAttribute("memberId");
        String nickname = (String) rq.getAttribute("nickname");

        List<OmsOrderItem> items = new ArrayList<>();

        // 调用购物车
        List<OmsCartItem> omsCartItems = (List<OmsCartItem>) cartService.cartList(memberId);


        if (isNotEmpty(omsCartItems)) {

            for (OmsCartItem omsCartItem : omsCartItems) {

                String isChecked = omsCartItem.getIsChecked();

                if (!(null == isChecked) && isChecked.equals("1")) {
                    OmsOrderItem omsOrderItem = new OmsOrderItem();


                    omsOrderItem.setProductName(omsCartItem.getProductName());
                    omsOrderItem.setProductPic(omsCartItem.getProductPic());
                    omsOrderItem.setProductPrice(omsCartItem.getPrice());
                    omsOrderItem.setProductQuantity(omsCartItem.getQuantity());

                    items.add(omsOrderItem);

                }


            }

        }

        BigDecimal totalAmount = _getTotalAmount(omsCartItems);


        List<UmsMemberReceiveAddress> umsMemberReceiveAddress = (List<UmsMemberReceiveAddress>)
                memberService.getMemberReceiveAddressByMemberId(memberId);

        Member member = (Member) memberService.getById(memberId);
        model.put("OmsOrderItems", items);
        model.put("totalAmount", totalAmount);
        model.put("userAddressList", umsMemberReceiveAddress);


        String tradeCode = orderService.genTradeCode(memberId);
        model.put("tradeCode", tradeCode);


        return "trade";
    }


    /**
     * Desc: 计算总价   ||
     * Param: [omsCartItems]    ||
     * Return: java.math.BigDecimal    ||
     */
    private BigDecimal _getTotalAmount(List<OmsCartItem> omsCartItems) {

        BigDecimal bigDecimal = omsCartItems.stream()
                                            .filter(check -> check.getIsChecked().equals("1")) // 过滤
                                            .map(item -> item.getTotalPrice())  // 转化
                                            .reduce((x, y) -> x.add(y).setScale(2, BigDecimal.ROUND_HALF_DOWN)).get();
        // 归约

        return bigDecimal;
    }

}
